using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Text;
using System.Xml.Serialization;
using Moly.Build;

namespace Moly.VB6
{
    public static class ExeModer
    {
        private const uint RtString = 6;

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr BeginUpdateResource(string pFileName,[MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources);
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool UpdateResource(IntPtr hUpdate, uint lpType, string lpName, ushort wLanguage, byte[] lpData, uint cbData);
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);

        public static void AddDependencyMeta(string target, IProject project)
        {
            var bytes = GetMetaData(project);

            var ipTarget = BeginUpdateResource(target, false);
            if (UpdateResource(ipTarget, RtString, "MetaData", 1033, bytes, (uint)bytes.Length))
            {
                EndUpdateResource(ipTarget, false);
                return;
            }

            throw new Exception("MetaData update Failed.");
        }

        private static byte[] GetMetaData(IProject project)
        {
            var ser = new DataContractSerializer(project.GetType());
            var mem = new MemoryStream();
            ser.WriteObject(mem, project);
            var sr = new StreamReader(mem);
            var dump = sr.ReadToEnd();

            var bytes = Encoding.Default.GetBytes(dump);
            return bytes;
        }
    }
}